<?php

/*
 * Plugin Name: SaveLink
 * Plugin URI: -----
 * Description: This plugin creates a copy of a webpage in a local file for selected links in a post.  It replaces the link in a post with the new link 
 * pointing to the local file.  It updates the metadata for a post with the original link and the new link
 * Version: 1.2
 * Author: Mark Tilly
 * Author URL: http://www.target-info.com
 * License: GPLv2 or later
/*
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

/*TO ADD NEW LOGINS:
 * Update the admin page with the new site
 * Update admin page POST processing to save site key, uname and pass
 * Update mct_sl_replink and add the new sites to the domain string append process at top
 * Update mct_sl_writepage to handle the new login and call
 * the new function which you also add
 */
/* v1.1 revisions
Made corrections to handle Multisite
- admin form post action updated
- Use Network site url and site url where appropriate
- Each blog has its own savelink directory
- check for directory before writing pages (not always updated in activation hook)
- Filter link to secure site to check user on save page redirects
- changed rewrite rule to focus on '/savelink/' as endpoint rule was always prefaced with 'blog'
  as was a new permalink tag

 */
global $blog_id, $blogname, $site_id;
//Set Version
define('MCT_SL_VERSION','V1.1');
//Disable Revisions - cause lots of problems with meta data and repeated updates
define('WP_POST_REVISIONS', false);
//Activation hook: Check for the directory and create it if not found
register_activation_hook(__FILE__, 'mct_sl_activehook');
//Deactivation hook, remove options, flush rewrites
register_deactivation_hook(__FILE__,'mct_sl_deactivate');
//Set up filter on postie to strip tags on html
//Postie can introduce style options in p and a tags 
//so clean that up too
add_filter('postie_post','mct_sl_postie');
// Directory for saved pages
if (is_multisite() && $blog_id != $site_id){
    define("MCT_SL_SAVEPAGES","mct-sl-savelink/".$blogname);
}else {
    define("MCT_SL_SAVEPAGES","mct-sl-savelink");
}
//SaveLink key
define("MCT_SL_SAVEKEY","sl:");
//Ailink redirect base
define (MCT_AI_REDIR,'ailink');
//Global pages table
$ai_sl_pages_tbl = $wpdb->prefix.'sl_pages';
//Global options array
$mct_sl_optarray = get_option('mct_sl_options');
// Add hook save_post to replace links and update metadata
add_action('save_post','mct_sl_replink');
//Metabox to show link data
add_action('add_meta_boxes','mct_sl_linkmeta');
//Admin Options page, single menu entry
add_action('admin_menu','mct_sl_addmenu');
//Remove file from disk if deleting post
add_action('before_delete_post','mct_sl_deletefile');
//add rewrite rule on init
add_action('init','mct_sl_add_rule');
//add filter on template redirect for endpoin rewrite
add_action('template_redirect','mct_sl_temp_redir');
add_filter('query_vars','mct_sl_qvar');
//Get login functions
include('savelink_fcns.php');

function mct_sl_activehook(){
    //Create the directory if not there
    global $mct_sl_optarray;
    mct_sl_chkdir();
    if (empty($mct_sl_optarray)){
        add_option('mct_sl_options');
    }
    //Redirect rules
    mct_sl_add_rule();
    flush_rewrite_rules();
    
    //Check/create db
    mct_sl_checkdb();
}

function mct_sl_deactivate(){
    delete_option('mct_sl_options');
    flush_rewrite_rules();
}

function mct_sl_chkdir(){
    $directoryName = MCT_SL_SAVEPAGES;
    if( !is_dir(ABSPATH.$directoryName) ){
	//make directory
	if( !mkdir( ABSPATH.$directoryName, 0755 ) ){
		die('Directory '.$directoryName.' could not be created!');
	}
    }    
}
function mct_sl_add_rule(){
    //add_rewrite_endpoint('savelink', EP_PERMALINK);
    add_rewrite_rule('.+?/savelink/([^/]+)/?$','index.php?slfile=$matches[1]','top');
    //add ailink rule for saved db pages
    add_rewrite_rule('^(.*)/?'.MCT_AI_REDIR.'/([^/]+)/?$','index.php?aipageid=$matches[2]','top');
}
function mct_sl_qvar($vars){
    $vars[]='slfile';  //save pages on disk
    $vars[]= 'aipageid';  //save pages in db link
    return $vars;
}
function mct_sl_temp_redir(){
    global $userdata, $ai_sl_pages_tbl, $currenturl;
    //Redirect based on save page redirection
    //
    //First try file saved on disk
    $filename = get_query_var('slfile');
    if ($filename != ''){
        $directoryName = MCT_SL_SAVEPAGES;
        $extension = ".html";
        if (is_multisite()){
            $full_url = network_site_url().$directoryName.'/'.$filename.$extension;
        } else {
            $full_url = site_url().'/'.$directoryName.'/'.$filename.$extension;
        }
        $secure = 'OK';
        $postid = 0;
        $url = urldecode($currenturl);
        $pos = preg_match('{/([^/]*)/savelink}',$url,$matches);
        if ($pos){
            $the_slug = $matches[1];
            $args=array(
              'name' => $the_slug,
              'post_type' => 'post',
              'post_status' => 'publish',
              'showposts' => 1
            );
            $my_posts = get_posts($args);
            $postid = $my_posts[0]->ID;
        }
        $secure = apply_filters('mct_sl_link_redir',$secure, $postid);
        if ($secure != 'OK'){
            return;
        }
        header('Content-Type: text/html');
        echo(file_get_contents($full_url));
        exit();
    }
    //Now try saved page in sl_pages
    $page_id = intval(get_query_var('aipageid'));

    if ($page_id != ''){
        $vals = mct_sl_getsavedpage($page_id);
        $page = $vals['sl_page_content'];
        $postid = $vals['sl_post_id'];
        if ($postid == NULL) $postid = 0;
        $secure = 'OK';
        $secure = apply_filters('mct_sl_link_redir',$secure, $postid);
        if ($secure != 'OK'){
            return;
        }
        
        $pos = preg_match('@Redirect{([^}]*)}@',$page,$matches);
        if ($pos){
            $sendback = wp_get_referer();  //How to get back
            header('Content-Type: text/html');
            header('Referer: '.$sendback);
            wp_redirect($matches[1]);
            exit;
            
        } else {
            header('Content-Type: text/html');
            echo($page);
            exit();
        }
    }
}

function mct_sl_getsavedpage($sl_id){
    //this function returns the page content and post id for a saved page given a page id
    global $ai_sl_pages_tbl, $wpdb;
    
    $sql = "SELECT `sl_page_content`, `sl_post_id`
            FROM $ai_sl_pages_tbl
            WHERE sl_page_id = '$sl_id'";
    $vals = $wpdb->get_row($sql, ARRAY_A);
    return $vals;
}

function mct_sl_deletefile($post_id){
    global $wpdb, $ai_sl_pages_tbl, $mct_ai_optarray;
    // Removes saved pages from disk/db
    // 
    //Get the meta data, and delete the new url's from disk
    $directoryName = MCT_SL_SAVEPAGES;
    $newlinks = get_post_meta($post_id,'mct_sl_newurl',true);
    for ($i=0;$i<count($newlinks);$i++){
        $pos = stripos($newlinks[$i],'savelink/');
        if ($pos !== false){
            $filename = ABSPATH.$directoryName.'/'.substr($newlinks[$i],$pos+9).'.html';
            if (stripos(ABSPATH,'\\') !== false) {
                $filename = str_ireplace('/','\\',$filename); // Backslashed file system, so change all
            }
            $filename = trim($filename);
            if (file_exists($filename))
                    $ret = unlink($filename);
        }
    }
    //Now try MCT_AI_REDIR pages
    if (!empty($newlinks)){
        foreach ($newlinks as $nlink){
            $pos = preg_match('{/'.MCT_AI_REDIR.'/(.*)$}',$nlink,$matches);  //stripos($newlinks[$i],'ailink/');
            if ($pos){
                $sl_id = intval(trim($matches[1]));
                $sql = "DELETE FROM $ai_sl_pages_tbl WHERE sl_page_id = $sl_id";
                $del = $wpdb->query($sql);
            }
        }
        //Delete featured image if being saved
        if ($mct_ai_optarray['ai_alt_theme']) {
            $thumb_id = get_post_meta($post_id, '_thumbnail_id',true);
            if ($thumb_id) wp_delete_attachment($thumb_id,true);
        }
    }
}

function mct_sl_postie($thepost){
    //Set postie to allow html in the body
    //Get rid of problem translating apostrophe in some subjects
    $titl = $thepost['post_title'];
    $pos = stripos($titl,'&acirc;');
    if ($pos !== false){
        $titl = substr($titl,0,$pos)."'".substr($titl,$pos+9);
    }
    //$vals = preg_match_all('@\x{FFFD}@u',$titl,$matches); - didn't work
    $thepost['post_title'] = $titl;
    $stripped = $thepost['post_content'];
    //First strip inline <style> tags with css between </style>
    $stripped = preg_replace('@<style[^>]*>[^<]*</style>@i','',$stripped);
    //now strip all tags except p, a
    $stripped =  strip_tags($stripped,'<p><a><br>');
    //Get rid of Style modifiers and other stuff inside the remaining tags
    //<p ....> should just be <p> ie get rid of style, ID etc
    $stripped = preg_replace('{<p[^>]*>}','<p>',$stripped);
    //<a ...  href  ... >  get rid of style info    
    $stripped = preg_replace('{<a ([^>]*)style\s*=\s*("|\')([^"\']*)("|\')([^>]*)>}i','<a $1$5>',$stripped);
    //<br ..../> should just be <br /> ie get rid of style, ID etc
    $stripped = preg_replace('{<br[^>]*>}','<br />',$stripped);
    $thepost['post_content'] = $stripped;
    //
    //Now check for categories using !c 
    $content = $thepost['post_content'];
    if ( preg_match('/!c ?([^!]*)!/i', $content, $matches))  {
        $content = str_replace($matches[0], "", $content);
        $thepost['post_content'] = $content;  //replace post content with tag stripped out
        $post_tags = preg_split("/,\s*/", $matches[1]);
    }
    if ( count( $post_tags )) {
        $post_tags = mct_sl_postieDB($post_tags, 'category');
        if (count($post_tags)) {
            $thepost['post_category'] = $post_tags;
        }
    }
    //Now check for tags using !t code 
    $content = $thepost['post_content'];
    if ( preg_match('/!t ?([^!]*)!/i', $content, $matches))  {
        $content = str_replace($matches[0], "", $content);
        $thepost['post_content'] = $content;  //replace post content with tag stripped out
        $post_tags = preg_split("/,\s*/", $matches[1]);
    }
    if ( count( $post_tags )) {
        $post_tags = mct_sl_postieDB($post_tags,'tag');
        if (count($post_tags)) {
            $thepost['tags_input'] = $post_tags;
        }
    }
    //Check for More tag and add it
    $content = $thepost['post_content'];
    $content = preg_replace('/(!m)/i','<!--more-->',$content);
    $thepost['post_content'] = $content;

    //Check for text bold to highlight our added text
    $content = $thepost['post_content'];
    if (stripos($content,'!b') !== false) {  //replace the !b with bold till end of line or a tag
        $content = preg_replace('/(!b) ?([^<|\n]*)([<|\n])/i', '<strong>$2</strong>$3',$content);
    } else { 
        //replace from start to first < with emphasis automatically 
        $content = preg_replace('/^([^<|\n]*)(<|\n)/', '<strong>$1</strong>$2',$content);
    }
    $thepost['post_content'] = $content;

    return $thepost;
}

function mct_sl_postieDB($taxon, $taxtype){
    //Checks for taxonomy on the database, hanndles partial matches
    //Removes any tags without a match - NOT allowing email post to create taxonomy
    global $wpdb;
    $post_taxon = array();
    if ($taxtype == 'tag'){
        $fldname = 'name';
    } else {
        $fldname = 'term_id';
    }
    foreach($taxon as $match) {
        $match = trim($match);
        $category = NULL;
        //print("Working on $match\n"); 

        $sql_name = 'SELECT '.$fldname.'
                     FROM ' . $wpdb->terms. ' 
                     WHERE name=\'' . addslashes($match) . '\'';
        $sql_id = 'SELECT '.$fldname.' 
                   FROM ' . $wpdb->terms. ' 
                   WHERE term_id=\'' . addslashes($match) . '\'';
        $sql_sub_name = 'SELECT '.$fldname.' 
                         FROM ' . $wpdb->terms. ' 
                         WHERE name LIKE \'' . addslashes($match) . '%\' limit 1';

        $category = $wpdb->get_var($sql_name);
        if ( !$category ) {
            //category not a complete name
            //try start of a name 
            $category = $wpdb->get_var($sql_sub_name);
            // forget ID for now        } elseif ( $category = $wpdb->get_var($sql_id) ) {
        }  
        if ($category) {
            $post_taxon[] = $category;
        }
    }
    return $post_taxon;
}


function mct_sl_replink($post_id){
/*Find the save link key sl: and check the do all flag
 *If found, find the link in the post - all of them
 *Write the web pages out to disk
 *Replace the link with the saved file
 *Update the post and save meta data (or error message if we couldn't save and leave sl key)
 */
    global $mct_sl_optarray, $wpdb;
    $image = '';  //Holder for the page image
    
    if (isset($_POST['restore_link']) || isset($_POST['image_source'])){
        if (isset($_POST['restore_link'])){
            mct_sl_restorelink($post_id);
            return;
        }
        if (isset($_POST['image_source'])){
            $image = esc_url($_POST['image_source']);
            update_post_meta($post_id, 'mct_sl_image',$image);
        }
    }
    $slkey = MCT_SL_SAVEKEY;
    //is this not final, if so return
    $data = get_post($post_id, ARRAY_A);
    if ( $data['post_status'] != 'publish')
        return;
        
    $post_dat = $data['post_content'];
    
    //See if we are to replace all links
    $has_key = false;
    $do_all = false;
    if ($mct_sl_optarray['save_all_pages'] == '1'){
        $do_all = true;
    }
    if (stripos($post_dat,$slkey) !== false) {
        //if save all pages is set, then treat the sl key as a 'do not save'
        if ($do_all == true){
            return;
        }
        $has_key = true;
        $do_all = true;  //same as do all
    }
    if ($do_all == false){
        return;   //not asked to save
    }
    // get the links, try escaped and unescaped quotes
    $link_arr = array();
    $num_links = 0;
    $regexp1 = '{<a [^>]*href\s*=\s*(\\\\"|.\')([^"\']*)(\\\\"|.\')[^>]*>}i';  //used .\' because couldn't end up with \' 
    $num_links1 = preg_match_all($regexp1,$post_dat, $matches1);
    $regexp2 = '{<a [^>]*href\s*=\s*("|\')([^"\']*)("|\')[^>]*>}i';  //Try unescaped - email posts and press-this
    $num_links2 = preg_match_all($regexp2,$post_dat, $matches2);
    if ($num_links1 != 0){
        foreach($matches1[2] as $lnk){
            array_push($link_arr,$lnk);
        }
        $num_links += $num_links1;
    }
    if ($num_links2 != 0){
        foreach($matches2[2] as $lnk){
            array_push($link_arr,$lnk);
        }
        $num_links += $num_links2;
    }
        //Any links to replace?
    if ($num_links == 0)
        return;  //nothing to do, no links

    //Set up some variables
    $any_error = false;
    $new_alinks = array();
    $old_alinks = array();
    $permalink = get_permalink($data['ID']);
    
    //For all link matches, replace the url with a local copy
    foreach ($link_arr as $oldlink) {
       // Make sure this hasn't been replace already
       if (stripos($oldlink,site_url())!== false)
               continue;
       //Skip .pdf files
       if (stripos($oldlink,'.pdf',strlen($oldlink)-4) !== false) {
           continue;
       }
       //Get the url and create a copy on disk
       $img = '';
       $sl_page_id  = mct_sl_writepage($oldlink,&$img, $post_id);
       if (!$sl_page_id){
           //Save failed so put in error text
           $newlink = "Error: Could not save a copy of web page";
           $any_error = true;
       }
       else {
           //Save image if not already
           if (empty($image) && !empty($img)) $image = $img;
           // add the url to the link
           $newlink = $permalink.MCT_AI_REDIR.'/'.trim(strval($sl_page_id));  
           //replace the link in the text - try both esc and un-esc
           $esc_oldlink = escape_string_for_regex($oldlink);
           $post_dat = preg_replace('{("|\')('.$esc_oldlink.')("|\')}','$1'.$newlink.'$3',$post_dat);  
           $post_dat = preg_replace('{(\\\\"|.\')('.$esc_oldlink.')(\\\\"|.\')}','$1'.$newlink.'$3',$post_dat);  
           //Replace link text and make 'nice'
           $post_dat = preg_replace('{>'.$esc_oldlink.'</a>}','>Click here to view the web page</a>',$post_dat);
       }
       //Load our links array
       array_push($new_alinks,$newlink);
       array_push($old_alinks,$oldlink);
    }
    if (count($old_alinks) == 0) {
        return;  //nothing found to update, links probably replaced already
    }
    //if !error replace the save key
    if (!$any_error && $has_key)
        $post_dat = str_ireplace($slkey,'',$post_dat);

    //update the database
    $where = array( 'ID' => $post_id );
    $wpdb->update( $wpdb->posts, array( 'post_content' => $post_dat ), $where );
    
    //Update the meta data
    //Check for existing meta and add on to new meta if found
    $orig_links = get_post_meta($post_id,'mct_sl_origurl',true);
    $new_links = get_post_meta($post_id,'mct_sl_newurl',true);
    if ($orig_links != '') {
        foreach ($orig_links as $link){
            array_push($old_alinks,$link);
        }
    }
    if ($new_links != ''){
        foreach ($new_links as $link) {
            array_push($new_alinks,$link);
        }
    }    
    update_post_meta($post_id,'mct_sl_origurl',$old_alinks);
    update_post_meta($post_id,'mct_sl_newurl',$new_alinks);    
    //update the image if found
    if (!empty($image)){
        update_post_meta($post_id, 'mct_sl_image',$image);
    }
}

function mct_sl_restorelink($post_id){
    global $wpdb;
    
    $data = get_post($post_id, ARRAY_A);
    $post_dat = $data['post_content'];
    //Get meta data
    $orig_links = get_post_meta($post_id,'mct_sl_origurl',true);
    $new_links = get_post_meta($post_id,'mct_sl_newurl',true);
    //replacement array ids
    $meta_id = $_POST['restore_link'];
    foreach ($meta_id as $meta){
       $pos = (int)$meta;
       $esc_newlink = escape_string_for_regex($new_links[$pos]);
       $post_dat = preg_replace('{("|\')('.$esc_newlink.')("|\')}','$1'.$orig_links[$pos].'$3',$post_dat);  
       $post_dat = preg_replace('{(\\\\"|.\')('.$esc_newlink.')(\\\\"|.\')}','$1'.$orig_links[$pos].'$3',$post_dat);          
    }
    //update the database
    $where = array( 'ID' => $post_id );
    $wpdb->update( $wpdb->posts, array( 'post_content' => $post_dat ), $where );
        
}

function mct_sl_writepage($url, $image, $postid){
    //Write the web page to disk, return the new file name or '' if failed
    //Also set the image src if found
    global $mct_sl_optarray, $wpdb, $ai_sl_pages_tbl;
    //$url = urlencode($url);
    
    $pageContent = '';
    //
    //Check for login domains - these take precedence
    $cookie = mct_ai_check_feed($url);
    if ($cookie == 'Fail') return 0;
    if ($cookie != ''){
        //we have logged in, so get the page
        $pageContent = mct_sl_postpage($url, $cookie);
    } else {
    //Not a login type so use standard capture
        $url = mct_ai_tw_expandurl($url);
        $pageContent = diffbot($url);
        if ($pageContent == ''){
            $pageContent = file_get_contents($url);  //Couldn't get just text so save whole page
            $pageContent = abs_url($url,$pageContent);
        }
    }

    if ($pageContent == '')
        return 0;
    // Get an image if we can - 1st match
    $regexp1 = '{<img [^>]*src\s*=\s*("|\')([^"\']*)("|\')[^>]*>}i'; 
    $pos = preg_match($regexp1,$pageContent,$matches);
    if ($pos){
        $image = $matches[2];
    }
    //Now write it out
    $wpdb->insert($ai_sl_pages_tbl, array (
        'sl_page_content' => $pageContent,
        'sl_post_id' => $postid));
    $page_id = $wpdb->insert_id;

    return $page_id;

}

function mct_sl_linkmeta(){
    add_meta_box('mct_sl_metabox','Link Replacement for SaveLink','mct_sl_linkmetashow','post','normal','high');
}

function mct_sl_linkmetashow($post){
    $origlinks = get_post_meta($post->ID,'mct_sl_origurl',true);
    $newlinks = get_post_meta($post->ID,'mct_sl_newurl',true);
    $image = get_post_meta($post->ID,'mct_sl_image',true);
    if ($origlinks == ''){
        return;
    }
    ?><table> <?php
    for ($i=0;$i<count($origlinks);$i++){
        ?>
    <tr>
        <td><input type="checkbox" name="restore_link[]" value="<?php echo($i); ?>"/><em>Restore: </em></td>
        <td><?php echo $origlinks[$i]; ?></td>
    </tr>
    <tr>
        <td><em>New Link: </em></td>
        <td><?php echo $newlinks[$i]; ?>
    </tr>
    <?php }  //end for loop ?>
    
    <tr>
        <td><em>Image Source:</em></td>
        <td><input type="text" name="image_source" maxlength="500" size ="100" value="<?php echo($image); ?>"/></td>
    </tr>
    
    </table> <?php
}

/* The functions below create and use the SaveLink admin page.  
 
 */
function mct_sl_addmenu(){
    add_options_page('SaveLink','SaveLink','manage_options',basename(__FILE__),'mct_sl_options_page');
}

//Page to display the form
function mct_sl_options_page() {
    
    mct_sl_checkdb();  //Make sure db is created

    if (isset($_POST['Submit']) ) {
        //load options into array and update db
        $opt_update = array (
            'version' => MCT_SL_VERSION,
            'save_all_pages' => $_POST['save_all_pages'],
        );
        update_option('mct_sl_options',$opt_update);
    }
    //Get the current option values from db
    $cur_options = get_option('mct_sl_options');

    ?>
<div class='wrap'>
    <?php screen_icon('link-manager'); ?>
    <h2>SaveLink</h2>
    <p>The SaveLink plugin allows you to create a local copy of a web page that you have linked to in one of your posts.
        You won't have to worry about whether the page is moved or deleted or placed behind a pay-wall.  
    </p>
    <h3>Manual and Automatic Saving</h3>
   <p>Check the "Save All Pages?" box to automatically save all pages locally, no matter which site they are from.  
      If this box is checked you can use the SaveLink key to request that a page Not be saved by placing it in the body of the post.</p>    
   <p>To manually save a copy of a web page if you are not saving all pages, enter the SaveLink key anywhere in the body of the post (not the title). 
        All of the links in the post will be saved, not just a single one.  Only well-formatted links will be saved.  
        The SaveLink key will be removed from the post when the web page has been saved and the link will be updated 
        to point to the new saved page.  In order to preserve your formatting, it is best to enter the SaveLink key at the
        beginning or end of a line - but it is not necessary. </p>
    <p><strong>The SaveLink key is <?php echo MCT_SL_SAVEKEY; ?> </strong></p>
    <form method="post" action="<?php echo $_SERVER['REQUEST_URI'] . '&updated=true"'; ?> >
        <table class="form-table" >
            <tr>
                <th scope="row">Save All Pages?</th>
                <td><input name="save_all_pages" type="checkbox" id="save_all_pages" value="1" <?php checked('1', $cur_options['save_all_pages']); ?>"  /></td></td>    
            </tr>
        </table>
        <div class="submit">
            <input name="Submit" type="submit" value="Save Options" class="button-primary" />
        </div>
        </form>
</div>
<?php
}

function mct_sl_checkdb(){
    global $wpdb, $ai_sl_pages_tbl;
    require_once(ABSPATH.'wp-admin/includes/upgrade.php');
    
    $sql = "CREATE TABLE `$ai_sl_pages_tbl` (
            `sl_page_id` int(11) NOT NULL AUTO_INCREMENT,
            `sl_page_content` longtext NOT NULL,
            `sl_post_id` int(11),
            PRIMARY KEY (`sl_page_id`)
    ) DEFAULT CHARSET=utf8 ;";
    dbDelta($sql);
}

function escape_string_for_regex($str)
{
        //All regex special chars (according to arkani at iol dot pt below):
        // \ ^ . $ | ( ) [ ]
        // * + ? { } ,
        
        $patterns = array('/\//', '/\^/', '/\./', '/\$/', '/\|/',
 '/\(/', '/\)/', '/\[/', '/\]/', '/\*/', '/\+/', 
'/\?/', '/\{/', '/\}/', '/\,/');
        $replace = array('\/', '\^', '\.', '\$', '\|', '\(', '\)', 
'\[', '\]', '\*', '\+', '\?', '\{', '\}', '\,');
        
        return preg_replace($patterns,$replace, $str);
}
?>
